<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>同时n次执行请求</title>
</head>

<body>

</body>
<script>
    // 并发请求函数
    const concurrencyRequest = (urls, maxNum) => {
        return new Promise((resolve) => {
            // 请求列表为空
            if (urls.length === 0) {
                resolve([]);
                return;
            }

            const results = []; // 保存 请求结果
            let index = 0; // 记录 下一个请求的下标

            // 发送请求
            async function request() {
                // 递归出口
                if (index === urls.length) return;

                const i = index; // 记录 使result和urls相对应
                const url = urls[index]; // 请求列表的单个请求地址
                console.log(url)
                try {
                    const resp = await fetch(url);
                    results[i] = resp; // resp加入到对应请求列表位置的results
                } catch (err) {
                    results[i] = err; // resp加入到对应请求列表位置的results
                } finally {
                    index++;  // 下一个请求

                    // 判断是否所有的请求都已完成
                    if (index === urls.length) {
                        console.log('完成了');
                        resolve(results);
                    }

                    // 递归下一次请求
                    request();
                }
            }

            // maxNum和urls.length取最小进行调用   同时请求几次
            const times = Math.min(maxNum, urls.length);
            for (let i = 0; i < times; i++) {
                request();
            }
        })
    }
    const urls = [];
    for (let i = 1; i <= 20; i++) {
        urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
    }

    // 执行
    (async () => {
        let res = await concurrencyRequest(urls, 3)
        console.log(res)
    })()


    
</script>

</html>